﻿/* 
 * Evo
 * 
 * Marcin Krupowicz (marcin@krupowicz.eu)
 * Barbara Szymanek (basia.szymanek@gmail.com)
 * 
 * January, 2009
 *
 */

using System;
using System.Collections.Generic;
using System.Text;

namespace Evo.Operators
{
	#region crossover operator with contribution
	public class ContributionCrossoverOperator<T> : CrossoverOperator<T>, IOperatorWithContribution<T> where T : IIndividual
	{
		int counter;
		double contribution = 0.0;
		double ratio;
		CrossoverOperator<T> myOperator;

		/// <summary>
		/// Create ContributionCrossoverOperator instance with given crossover operator
		/// </summary>
		/// <param name="crossOperator">crossover operator</param>
		public ContributionCrossoverOperator(CrossoverOperator<T> crossOperator) :
			base()
		{
			this.myOperator = crossOperator;
			this.parentNeeded = myOperator.Arity;
			this.parentNeeded = myOperator.ParentArity;
		}

		/// <summary>
		/// Get contribution
		/// </summary>
		public double Contribution
		{
			get { return contribution; }
		}

		/// <summary>
		/// Get/set ratio
		/// </summary>
		public double Ratio
		{
			get { return ratio; }
			set { ratio = value; }
		}

		public override string ToString()
		{
			return myOperator.ToString() + "\n\tRatio: " +
				String.Format(System.Globalization.CultureInfo.InvariantCulture.NumberFormat, "{0}", ratio);
		}

		/// <summary>
		/// Crossover
		/// </summary>
		/// <param name="parents">list of parents to be crossovered</param>
		/// <returns>list of children</returns>
		public override List<T> Crossover(List<T> parents)
		{
			return this.myOperator.Crossover(parents);
		}

		/// <summary>
		/// Crossover whole population
		/// </summary>
		/// <param name="population">popultion</param>
		/// <returns>new population</returns>
		public override Population<T> Execute(Population<T> population)
		{
			populationSize = population.Size;

			//select parents -- to jest niepotrzebne, dostaje parentsow od algorytmu

			//    if (parentSelectionOperator != null)

			//      parents = parentSelectionOperator.Execute(population);

			parents = population;

			List<T> childrenIndividuals = new List<T>();
			List<T> parentGroup;

			List<T> toAdd = new List<T>();      //liczymy wartosci do contribution


			parentCounter = 0;
			counter = 0;
			double parentValue;
			double childValue;
			double singleContr = 0;

			while (true)
			{
				parentGroup = getNextParentsGroup();
				if (parentGroup == null)
					break;

				//set contribution

				toAdd = Crossover(parentGroup);

				parentValue = 0;
				childValue = 0;
				foreach (T ind in parentGroup)
					parentValue += ind.Value;

				foreach (T ind in toAdd)
				{
					ind.ObjectiveFunction = parentGroup[0].ObjectiveFunction;
					childValue += ind.Value;
				}

				if (parentValue < childValue)
					singleContr += Math.Abs(parentValue - childValue);

				counter++;
				//end set contribution


				childrenIndividuals.AddRange(toAdd);
			}

			contribution += singleContr / (double)counter;

			children = new Population<T>(childrenIndividuals);
			//robimy to wyzej

			//children.ObjectiveFunction = population[0].ObjectiveFunction;


			//zwraca dzieci

			return children;
		}
	}
	#endregion

	#region abstract CrossoverOperator
	/// <summary>
	/// Abstract class for crossover operator
	/// </summary>
	/// <typeparam name="T"></typeparam>
	public abstract class CrossoverOperator<T> : IOperator<T> where T : IIndividual
	{
		#region fields
		protected Random random = new Random(DateTime.Now.Millisecond);
		protected int arity;
		protected int parentNeeded;
		protected int populationSize;
		protected int parentCounter;

		protected IOperator<T> parentSelectionOperator;
		protected IReplacementOperator<T> replacementOperator;

		protected Population<T> parents;
		protected Population<T> children;
		#endregion

		#region properties
		/// <summary>
		/// Get/set method of parent selection
		/// </summary>
		public IOperator<T> ParentSelection
		{
			get { return parentSelectionOperator; }
			set { parentSelectionOperator = value; }
		}

		/// <summary>
		/// Get/set method of replacement
		/// </summary>
		public IReplacementOperator<T> ReplacementOperator
		{
			get { return replacementOperator; }
			set { replacementOperator = value; }
		}

		/// <summary>
		/// Get size of population
		/// </summary>
		public int PopulationSize
		{
			get
			{
				return populationSize;
			}
		}

		/// <summary>
		/// Get arity of operator
		/// </summary>
		public int Arity
		{
			get { return arity; }
		}

		/// <summary>
		/// Get parent arity (required number of parents for one crossover)
		/// </summary>
		public int ParentArity
		{
			get { return parentNeeded; }
		}

		#endregion

		#region constructors
		/// <summary>
		/// Create new instance of crossover operator with default parent selection and replacement
		/// </summary>
		public CrossoverOperator()
		{
			this.parentCounter = 0;
		}

		/// <summary>
		/// Create new instance of crossover operator with given parent selection and replacement methods
		/// </summary>
		/// <param name="parentSelection">parent selection method</param>
		/// <param name="replacement">replacement method</param>
		public CrossoverOperator(IOperator<T> parentSelection, IReplacementOperator<T> replacement)
		{
			this.parentSelectionOperator = parentSelection;
			this.replacementOperator = replacement;
			this.parentCounter = 0;
		}

		#endregion

		#region methods
		/// <summary>
		/// Execute crossover
		/// </summary>
		/// <param name="population">population</param>
		/// <returns>new population</returns>
		public virtual Population<T> Execute(Population<T> population)
		{
			populationSize = population.Size;

			//select parents

			if (parentSelectionOperator != null)
				parents = parentSelectionOperator.Execute(population);
			else parents = population;

			List<T> childrenIndividuals = new List<T>();
			List<T> parentGroup;

			parentCounter = 0;

			while (true)
			{
				parentGroup = getNextParentsGroup();
				if (parentGroup == null)
					break;

				childrenIndividuals.AddRange(Crossover(parentGroup));
			}
			children = new Population<T>(childrenIndividuals);

			children.ObjectiveFunction = population[0].ObjectiveFunction;

			//zrob replacement

			if (replacementOperator != null)
				return replacementOperator.Replace(parents, children, population); //a moze powinno byc population, children?


			else return defaultReplacement(population);    //population?

		}

		protected Population<T> defaultReplacement(Population<T> parentPopulation)
		{
			List<T> toReturn = children.Individuals;
			if (populationSize > toReturn.Count)
			{
				//dodaj najlepszych z rodzicow

				toReturn.AddRange(Selection<T>.KBestSelection(parentPopulation, populationSize - toReturn.Count).Individuals);
			}
			else if (populationSize < toReturn.Count)
			{
				//zwroc tylko najlepsze dzieci

				return Selection<T>.KBestSelection(children, populationSize);
			}
			return new Population<T>(toReturn);
		}

		protected List<T> getNextParentsGroup()
		{
			List<T> toCross = new List<T>();
			if (parentCounter + parentNeeded > parents.Size)
				return null;

			for (int i = 0; i < parentNeeded; i++, parentCounter++)
			{
				toCross.Add(parents[parentCounter]);
			}
			return toCross;
		}

		public override string ToString()
		{
			String selection;
			String reproduction;
			if (this.parentSelectionOperator == null)
				selection = " default selection (all population use as parents) ";
			else selection = this.parentSelectionOperator.ToString();

			if (this.replacementOperator == null)
				reproduction = " default reproduction (children + parents = new population) ";
			else reproduction = this.replacementOperator.ToString();

			String myName = String.Format("{0}\nParent selection: {1}\nReproduction: {2}\n",
				this.GetType().ToString(), selection, reproduction);

			return myName;
		}

		public abstract List<T> Crossover(List<T> parents);
		#endregion
	}
	#endregion

	#region CrossoverOperators for PermutationIndividual

	/// <summary>
	/// NABEL crossover operator. Based on non-abelian groups. Works on PermutationIndividual.
	/// </summary>
	public class NABELCrossoverOperator : CrossoverOperator<PermutationIndividual>
	{
		#region constructors
		public NABELCrossoverOperator()
			: base()
		{
			this.arity = 2;
			this.parentNeeded = 2;
		}

		public NABELCrossoverOperator(IOperator<PermutationIndividual> parentSelection,
			IReplacementOperator<PermutationIndividual> replacement)
			: base(parentSelection, replacement)
		{
			this.arity = 2;
			this.parentNeeded = 2;
		}

		#endregion

		#region methods
		public override List<PermutationIndividual> Crossover(List<PermutationIndividual> parents)
		{
			IntegerChromosome parent1Chromosome = (IntegerChromosome)parents[0].Chromosome;
			IntegerChromosome parent2Chromosome = (IntegerChromosome)parents[1].Chromosome;

			IntegerChromosome child1Chromosome = new IntegerChromosome(parent1Chromosome.Length);
			IntegerChromosome child2Chromosome = new IntegerChromosome(parent1Chromosome.Length);

			for (int i = 0; i < child1Chromosome.Length; i++)
			{
				child1Chromosome[i] = parent1Chromosome[parent2Chromosome[i]];
				child2Chromosome[i] = parent2Chromosome[parent1Chromosome[i]];
			}

			List<PermutationIndividual> children = new List<PermutationIndividual>();
			children.Add(new PermutationIndividual(child1Chromosome));
			children.Add(new PermutationIndividual(child2Chromosome));

			return children;
		}
		#endregion

	}

	/// <summary>
	/// LOX (Linear Order Crossover) crossover operator. Works on PermutationIndividual.
	/// </summary>
	public class LOXCrossoverOperator : CrossoverOperator<PermutationIndividual>
	{
		#region constructors
		public LOXCrossoverOperator()
			: base()
		{
			this.arity = 2;
			this.parentNeeded = 2;
		}

		public LOXCrossoverOperator(IOperator<PermutationIndividual> parentSelection,
			IReplacementOperator<PermutationIndividual> replacement)
			: base(parentSelection, replacement)
		{
			this.arity = 2;
			this.parentNeeded = 2;
		}
		#endregion


		#region methods
		private void copySegment(int from, int to, IntegerChromosome childChromosome, IntegerChromosome parentChromosome)
		{
			for (int i = from; i < to; i++)
				childChromosome[i] = parentChromosome[i];
		}

		private bool geneIsInChromosome(int from, int to, int gene, IntegerChromosome chromosome)
		{
			for (int i = from; i < to; i++)
			{
				if (chromosome[i] == gene)
					return true;
			}
			return false;
		}

		public override List<PermutationIndividual> Crossover(List<PermutationIndividual> parents)
		{
			PermutationIndividual parent1 = parents[0];
			PermutationIndividual parent2 = parents[1];

			int startSegment = random.Next(0, parent1.ChromosomeLength);
			int endSegment = random.Next(startSegment + 1, parent1.ChromosomeLength + 1);

			IntegerChromosome parent1Chromosome = (IntegerChromosome)parent1.Chromosome;
			IntegerChromosome parent2Chromosome = (IntegerChromosome)parent2.Chromosome;
			IntegerChromosome child1Chromosome = new IntegerChromosome(parent1.ChromosomeLength);
			IntegerChromosome child2Chromosome = new IntegerChromosome(parent1.ChromosomeLength);

			copySegment(startSegment, endSegment, child1Chromosome, parent1Chromosome);
			copySegment(startSegment, endSegment, child2Chromosome, parent2Chromosome);

			fillRestOfChromosome(startSegment, endSegment, child1Chromosome, parent2Chromosome);
			fillRestOfChromosome(startSegment, endSegment, child2Chromosome, parent1Chromosome);

			List<PermutationIndividual> children = new List<PermutationIndividual>();
			children.Add(new PermutationIndividual(child1Chromosome));
			children.Add(new PermutationIndividual(child2Chromosome));

			return children;
		}

		private void fillRestOfChromosome(int start, int stop, IntegerChromosome childChromosome, IntegerChromosome parentChromosome)
		{
			int childIndex;
			int parentIndex;
			int gene;

			int chromosomeLength = childChromosome.Length;

			for (childIndex = 0, parentIndex = 0; childIndex < start;
				childIndex++, parentIndex++)
			{
				gene = parentChromosome[parentIndex];
				while (geneIsInChromosome(start, stop, gene, childChromosome))
					gene = parentChromosome[++parentIndex];

				childChromosome[childIndex] = gene;
			}

			for (childIndex = childChromosome.Length - 1, parentIndex = childChromosome.Length - 1;
					childIndex >= stop; childIndex--, parentIndex--)
			{
				gene = parentChromosome[parentIndex];

				while (geneIsInChromosome(start, stop, gene, childChromosome))
					gene = parentChromosome[--parentIndex];

				childChromosome[childIndex] = gene;
			}
		}

		#endregion
	}


	/// <summary>
	/// OX (Order Crossover) crossover operator. Works on PermutationIndividual.
	/// </summary>
	public class OXCrossoverOperator : CrossoverOperator<PermutationIndividual>
	{
		#region constructors
		public OXCrossoverOperator()
			: base()
		{
			this.arity = 2;
			this.parentNeeded = 2;
		}

		public OXCrossoverOperator(IOperator<PermutationIndividual> parentSelection,
			IReplacementOperator<PermutationIndividual> replacement)
			: base(parentSelection, replacement)
		{
			this.arity = 2;
			this.parentNeeded = 2;
		}
		#endregion


		#region methods
		private void copySegment(int from, int to, IntegerChromosome childChromosome, IntegerChromosome parentChromosome)
		{
			for (int i = from; i < to; i++)
				childChromosome[i] = parentChromosome[i];
		}

		private bool geneIsInChromosome(int from, int to, int gene, IntegerChromosome chromosome)
		{
			for (int i = from; i < to; i++)
			{
				if (chromosome[i] == gene)
					return true;
			}
			return false;
		}

		private void fillRestOfChromosome(int start, int stop, IntegerChromosome childChromosome, IntegerChromosome parentChromosome)
		{
			int childIndex;
			int parentIndex;
			int gene;

			int chromosomeLength = childChromosome.Length;

			for (childIndex = start, parentIndex = start;
					childIndex != stop; childIndex++, parentIndex++)
			{
				if (childIndex == chromosomeLength)
					childIndex = 0;
				if (parentIndex == chromosomeLength)
					parentIndex = 0;

				gene = parentChromosome[parentIndex];

				if (geneIsInChromosome(stop, start, gene, childChromosome))
					childIndex--;
				else childChromosome[childIndex] = gene;
			}
		}

		public override List<PermutationIndividual> Crossover(List<PermutationIndividual> parents)
		{
			PermutationIndividual parent1 = parents[0];
			PermutationIndividual parent2 = parents[1];

			int startSegment = random.Next(0, parent1.ChromosomeLength);
			int endSegment = random.Next(startSegment + 1, parent1.ChromosomeLength + 1);

			IntegerChromosome child1Chromosome = new IntegerChromosome(parent1.ChromosomeLength);
			IntegerChromosome child2Chromosome = new IntegerChromosome(parent1.ChromosomeLength);

			copySegment(startSegment, endSegment, child1Chromosome, (IntegerChromosome)parent1.Chromosome);
			copySegment(startSegment, endSegment, child2Chromosome, (IntegerChromosome)parent2.Chromosome);


			fillRestOfChromosome(endSegment, startSegment, child1Chromosome, (IntegerChromosome)parent2.Chromosome);
			fillRestOfChromosome(endSegment, startSegment, child2Chromosome, (IntegerChromosome)parent1.Chromosome);

			List<PermutationIndividual> children = new List<PermutationIndividual>();
			children.Add(new PermutationIndividual(child1Chromosome));
			children.Add(new PermutationIndividual(child2Chromosome));

			return children;
		}
		#endregion
	}

	/// <summary>
	/// PMX (Partial-Mapped Crossover) crossover operator. Works on PermutationIndividual.
	/// </summary>
	public class PMXCrossoverOperator : CrossoverOperator<PermutationIndividual>
	{
		#region constructors
		public PMXCrossoverOperator()
			: base()
		{
			this.arity = 2;
			this.parentNeeded = 2;

		}

		public PMXCrossoverOperator(IOperator<PermutationIndividual> parentSelection, IReplacementOperator<PermutationIndividual> replacement)
			: base(parentSelection, replacement)
		{
			this.arity = 2;
			this.parentNeeded = 2;
		}
		#endregion

		private void copySegment(int from, int to, IntegerChromosome childChromosome, IntegerChromosome parentChromosome)
		{
			for (int i = from; i < to; i++)
				childChromosome[i] = parentChromosome[i];
		}

		private int geneIsInChromosome(int from, int to, int gene, IntegerChromosome chromosome)
		{
			for (int i = from; i < to; i++)
			{
				if (chromosome[i] == gene)
					return i;
			}
			return -1;
		}

		private void fillRestOfChromosome(int startSegment, int endSegment, IntegerChromosome childChromosome,
			IntegerChromosome brotherChromosome, IntegerChromosome parentChromosome)
		{
			int index = 0;
			int gene;
			int conflictPosition;

			if (startSegment == 0)
				index = endSegment;

			int chromosomeLength = childChromosome.Length;
			for (; index < chromosomeLength; index++)
			{
				gene = parentChromosome[index];
				conflictPosition = geneIsInChromosome(startSegment, endSegment, gene, childChromosome);

				while (conflictPosition != -1)
				{
					gene = brotherChromosome[conflictPosition];
					conflictPosition = geneIsInChromosome(startSegment, endSegment, gene, childChromosome);
				}
				childChromosome[index] = gene;

				if (index == startSegment - 1)
					index = endSegment - 1;
			}
		}


		public override List<PermutationIndividual> Crossover(List<PermutationIndividual> parents)
		{
			PermutationIndividual parent1 = parents[0];
			PermutationIndividual parent2 = parents[1];

			int startSegment = random.Next(0, parent1.ChromosomeLength);
			int endSegment = random.Next(startSegment + 1, parent1.ChromosomeLength + 1);

			IntegerChromosome child1Chromosome = new IntegerChromosome(parent1.ChromosomeLength);
			IntegerChromosome child2Chromosome = new IntegerChromosome(parent1.ChromosomeLength);

			copySegment(startSegment, endSegment, child1Chromosome, (IntegerChromosome)parent1.Chromosome);
			copySegment(startSegment, endSegment, child2Chromosome, (IntegerChromosome)parent2.Chromosome);

			fillRestOfChromosome(startSegment, endSegment, child1Chromosome, child2Chromosome, (IntegerChromosome)parent2.Chromosome);
			fillRestOfChromosome(startSegment, endSegment, child2Chromosome, child1Chromosome, (IntegerChromosome)parent1.Chromosome);

			List<PermutationIndividual> children = new List<PermutationIndividual>();
			children.Add(new PermutationIndividual(child1Chromosome));
			children.Add(new PermutationIndividual(child2Chromosome));

			return children;
		}

	}

	/// <summary>
	/// CX (Cycle Crossover) crossover operator. Works on PermutationIndividual.
	/// </summary>
	public class CXCrossoverOperator : CrossoverOperator<PermutationIndividual>
	{
		#region constructors
		public CXCrossoverOperator()
			: base()
		{
			this.arity = 2;
			this.parentNeeded = 2;

		}

		public CXCrossoverOperator(IOperator<PermutationIndividual> parentSelection, IReplacementOperator<PermutationIndividual> replacement)
			: base(parentSelection, replacement)
		{
			this.arity = 2;
			this.parentNeeded = 2;
		}
		#endregion

		public override List<PermutationIndividual> Crossover(List<PermutationIndividual> parents)
		{
			PermutationIndividual parent1 = parents[0];
			PermutationIndividual parent2 = parents[1];

			int length = parent1.ChromosomeLength;

			IntegerChromosome parent1Chromosome = (IntegerChromosome)parent1.Chromosome;
			IntegerChromosome parent2Chromosome = (IntegerChromosome)parent2.Chromosome;
			IntegerChromosome child1Chromosome = new IntegerChromosome(length);
			IntegerChromosome child2Chromosome = new IntegerChromosome(length);

			for (int i = 0; i < parent1.ChromosomeLength; i++)
			{
				child1Chromosome[i] = -1;
				child2Chromosome[i] = -1;
			}

			int[] geneIsInPositionInParent1 = new int[length];

			for (int i = 0; i < length; i++)
			{
				geneIsInPositionInParent1[parent1Chromosome[i]] = i;
			}

			int j = 0;          //chodzimy po cyklu

			int gene1 = 0;      // j-ty gen parenta1

			int gene2 = 0;      // j-ty gen parenta2

			int cycles = 0;     // ile cykli


			for (int i = 0; i < length; i++)
			{
				//jesli jeszcze tu nas nie bylo

				if (child1Chromosome[i] == -1)
				{
					j = i;          //startujemy

					do
					{
						gene1 = parent1Chromosome[j];
						gene2 = parent2Chromosome[j];

						//na przemian z ojca1 do dziecka1 /  z ojca1 do dzicka2

						if (cycles % 2 == 0)
						{
							child1Chromosome[j] = gene1;
							child2Chromosome[j] = gene2;
						}
						else
						{
							child1Chromosome[j] = gene2;
							child2Chromosome[j] = gene1;
						}

						j = geneIsInPositionInParent1[gene2];
					} while (i != j);

					cycles++;
				}
			}

			List<PermutationIndividual> children = new List<PermutationIndividual>();
			children.Add(new PermutationIndividual(child1Chromosome));
			children.Add(new PermutationIndividual(child2Chromosome));

			return children;
		}
	}

	#endregion

	#region CrossoverOperators for RealInvidual
	/// <summary>
	/// One point crossover
	/// </summary>
	public class OnePointCrossoverOperator : CrossoverOperator<RealIndividual>
	{
		#region constructors
		public OnePointCrossoverOperator()
			: base()
		{
			this.arity = 2;
			this.parentNeeded = 2;
		}

		public OnePointCrossoverOperator(IOperator<RealIndividual> parentSelection,
			IReplacementOperator<RealIndividual> replacement)
			: base(parentSelection, replacement)
		{
			this.arity = 2;
			this.parentNeeded = 2;
		}

		#endregion

		#region methods
		public override List<RealIndividual> Crossover(List<RealIndividual> parents)
		{
			RealChromosome parent1Chromosome = (RealChromosome)parents[0].Chromosome;
			RealChromosome parent2Chromosome = (RealChromosome)parents[1].Chromosome;
			int chromosomeLength = parent1Chromosome.Length;

			RealChromosome child1Chromosome = new RealChromosome(chromosomeLength);
			RealChromosome child2Chromosome = new RealChromosome(chromosomeLength);

			int cutPoint = random.Next(1, chromosomeLength);
			for (int i = 0; i < cutPoint; i++)
			{
				child1Chromosome[i] = parent2Chromosome[i];
				child2Chromosome[i] = parent1Chromosome[i];
			}

			for (int i = cutPoint; i < chromosomeLength; i++)
			{
				child1Chromosome[i] = parent1Chromosome[i];
				child2Chromosome[i] = parent2Chromosome[i];
			}

			List<RealIndividual> children = new List<RealIndividual>();
			children.Add(new RealIndividual(child1Chromosome));
			children.Add(new RealIndividual(child2Chromosome));

			return children;
		}
		#endregion
	}

	/// <summary>
	/// Two point crossover
	/// </summary>
	public class TwoPointCrossoverOperator : CrossoverOperator<RealIndividual>
	{
		#region constructors
		public TwoPointCrossoverOperator()
			: base()
		{
			this.arity = 2;
			this.parentNeeded = 2;
		}

		public TwoPointCrossoverOperator(IOperator<RealIndividual> parentSelection,
			IReplacementOperator<RealIndividual> replacement)
			: base(parentSelection, replacement)
		{
			this.arity = 2;
			this.parentNeeded = 2;
		}

		#endregion

		#region methods
		public override List<RealIndividual> Crossover(List<RealIndividual> parents)
		{
			RealChromosome parent1Chromosome = (RealChromosome)parents[0].Chromosome;
			RealChromosome parent2Chromosome = (RealChromosome)parents[1].Chromosome;
			int chromosomeLength = parent1Chromosome.Length;

			RealChromosome child1Chromosome = new RealChromosome(chromosomeLength);
			RealChromosome child2Chromosome = new RealChromosome(chromosomeLength);

			int cutPoint1 = random.Next(1, chromosomeLength - 1);
			int cutPoint2 = random.Next(cutPoint1, chromosomeLength);
			for (int i = 0; i < cutPoint1; i++)
			{
				child1Chromosome[i] = parent2Chromosome[i];
				child2Chromosome[i] = parent1Chromosome[i];
			}
			for (int i = cutPoint1; i < cutPoint2; i++)
			{
				child1Chromosome[i] = parent1Chromosome[i];
				child2Chromosome[i] = parent2Chromosome[i];
			}
			for (int i = cutPoint2; i < chromosomeLength; i++)
			{
				child1Chromosome[i] = parent2Chromosome[i];
				child2Chromosome[i] = parent1Chromosome[i];
			}

			List<RealIndividual> children = new List<RealIndividual>();
			children.Add(new RealIndividual(child1Chromosome));
			children.Add(new RealIndividual(child2Chromosome));

			return children;
		}
		#endregion
	}
	#endregion
}
